package reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author 小小唐
 * @Date 2022/9/11-星期日-9:07
 *
 * 分析执行调用的性能问题
 */
public class Demo9 {

    //普通方式执行调用
    public static void test1(){

        User user = new User();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通方法执行调用10亿次："+(endTime-startTime)+"ms");

    }

    //反射方式执行调用
    public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();

        Method getName = c1.getDeclaredMethod("getName", null);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射方式执行调用10亿次："+(endTime-startTime)+"ms");
    }

    //关闭检测 执行调用
    public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();

        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);//关闭安全检测
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }

        long endTime = System.currentTimeMillis();
        System.out.println("关闭检测执行调用10亿次："+(endTime-startTime)+"ms");
    }

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        /*
        注意！注意！注意！
        普通方式（s1）执行调用所耗时间最短，执行效率最高
        正常反射方式(s2)执行调用所耗时间最长，执行效率最低
        而关闭安全检测后的反射方式(s3)执行调用时间为正常反射方式的一倍，执行效率相对于普通方式明显不如，相对于正常反射方式明显提高。
        根据不同方式的执行效率，故而有：
             s1 > s3 > s2
         */
        test1();
        test2();
        test3();
    }
}
